<script setup lang="ts">
import { isEmpty } from 'lodash'
import { ElInput, ElSelect, ElSwitch, ElRadioGroup } from 'element-plus'
import type { FormInstance } from 'element-plus'

const props = defineProps({
  config: {
    type: Object,
    default() {
      return {}
    },
  },
})

const compsMap: { [key: string]: any } = shallowRef({
  input: ElInput,
  select: ElSelect,
  switch: ElSwitch,
  radio: ElRadioGroup,
  span: 'span',
})

const formRef = ref<FormInstance | any>(null)
defineExpose({
  formRef,
})

const getSpanValue = (col: any) => {
  const value = props.config.form[col.key]
  if (isEmpty(value)) return ''
  if (isEmpty(col.options)) {
    return value
  }
  return col.options.find((d: any) => d.value == value).label
}
</script>

<template>
  <el-form
    class="js-form"
    ref="formRef"
    :label-position="config.labelPosition"
    :label-width="config.labelWidth ? config.labelWidth : 'auto'"
    :model="config.form"
    :rules="config.rules"
  >
    <el-row v-if="config.title && config.title.length > 0">
      <el-col>
        <span class="form-title">{{ config.title }}</span>
      </el-col>
    </el-row>
    <el-row v-for="(row, index) in config.rows" :key="index">
      <el-col :span="24 / row.length" v-for="(col, index) in row" :key="index">
        <el-form-item
          v-if="!col.hidden"
          class="js-form-item"
          :prop="col.key"
          :class="{
            'no-lable': col.label == undefined || col.label.length == 0,
          }"
        >
          <template #label>
            <span class="js-form-label">{{
              col.label && col.label.length > 0 ? col.label + ':' : ''
            }}</span>
          </template>
          <slot :name="col.key" :col="col" :value="config.form[col.key]">
            <component
              :is="compsMap[col.el]"
              @change="col.event"
              :placeholder="col.placeholder"
              v-model="config.form[col.key]"
              :disabled="col.disabled"
            >
              <template v-if="col.el == 'select'">
                <el-option
                  v-for="item in col.options"
                  :key="item.value"
                  :label="item.label"
                  :value="item.value"
                />
              </template>
              <template v-if="col.el == 'radio'">
                <el-radio
                  v-for="item in col.options"
                  :key="item.value"
                  :label="item.value"
                  :disabled="item.disabled"
                  >{{ item.label }}</el-radio
                >
              </template>
              <template v-if="col.el == 'span'">
                {{ getSpanValue(col) }}
              </template>
            </component>
          </slot>
        </el-form-item>
      </el-col>
    </el-row>
    <el-row v-if="config.btns">
      <el-col class="btns">
        <el-button
          v-for="btn in config.btns"
          :key="btn.label"
          :type="btn.type ? btn.type : 'primary'"
          @click="btn.event"
          size="small"
          >{{ btn.label }}</el-button
        >
      </el-col>
    </el-row>
  </el-form>
</template>

<style lang="scss" scoped>
.js-form {
  width: 100%;
  height: 100%;
  max-width: 800px;
  .js-form-label {
    font-size: 14px;
  }
  .no-lable {
    :deep(.el-form-item__label) {
      display: none !important;
    }
  }
  :deep(.el-form-item__error) {
    margin-left: 10px;
  }

  .btns {
    display: flex;
    justify-content: center;
    align-items: center;
  }
  .form-title {
    display: block;
    color: #606266;
    font-size: 16px;
    font-weight: 700;
    padding-bottom: 20px;
    padding-left: 10px;
  }
}
</style>
